Wiki
Clone wikiBibSonomy / development / modules / webapp / Spring Security
Overview
NOTE: outdated, TODO: please add a documentation for Shibboleth
The following classes are currently involved in user authentication:
- org.bibsonomy.webapp.controller.actions.UserLoginController
- org.bibsonomy.webapp.controller.actions.PasswordReminderController
- org.bibsonomy.webapp.controller.actions.PasswordChangeOnRemindController
- org.bibsonomy.webapp.controller.actions.ChangePasswordController
- org.bibsonomy.webapp.util.RequestWrapperContext
- org.bibsonomy.webapp.controller.actions.DeleteUserController
(all can be found in the webapp module)
Config-File
spring security
<bean:beans xmlns="http://www.springframework.org/schema/security" xmlns:bean="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd"> <http> <!-- no filtering for css and js --> <intercept-url pattern="/resources/**" filter="none" /> <!-- api uses own authentication handling --> <intercept-url pattern="/api/**" filter="none" /> <!-- login --> <intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <!-- restrict admin pages to admins --> <intercept-url pattern="/admin/**" access="ROLE_ADMIN" /> <!-- everything else --> <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <remember-me key="CURRENT_USER" token-validity-seconds="3600" /> TODO: ?!? <http-basic /> TODO <logout invalidate-session="true" logout-success-url="/" logout-url="/logout" /> <form-login login-page="/login" /> <session-management> <!-- only one session; if logged in user logs in a second time the first session becomes invalid --> <concurrency-control max-sessions="1" /> <!-- web.xml add listener HttpSessionEventPublischer TODO: or with error error-if-maximum-exceeded="true" and <session-authentication-error-url />--> </session-management> </http> <authentication-manager> <authentication-provider user-service-ref="authenticationProvider"> <password-encoder hash="md5"/> </authentication-provider> </authentication-manager> <bean:bean id="authenticationProvider" class="org.bibsonomy.webapp.util.spring.security.UserDetailsProvider"> <custom-authentication-provider /> <bean:property name="adminLogic" ref="adminLogic" /> </bean:bean>
web.xml
<listener> <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class> </listener> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <!-- so sollte Spring security im bibsonomy2-servlet context laufen --> <init-param> <param-name>contextAttribute</param-name> <param-value>org.springframework.web.servlet.FrameworkServlet.CONTEXT.bibsonomy2</param-value> </init-param> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Please not the init parameter of the DelegatingFilterProxy
which moves the Spring Security context into the webapp context.
Spring Security
Filter Overview
The DelegatingFilterProxy
loads/delegates to the FilterChainProxy. This proxy knows which filter are responsible for which path. Currently the following filters are registrated:
- /resources/** no filters
- /resources_puma/** no filters
- /api/** no filters
- /**
- The SecurityContextPersistenceFilter loads and saves the security context
- The LogoutFilter is responsible to logout the user. For that he uses different LogoutHandler; following logout handlers are registered:
- SecurityContextLogoutHandler invalides the session
- every RememberMeService (Intern, LDAP, OpenID) to delete the cookie of the corresponding login method
- PreAuthenticationFilter (e.g. X509)
- HTTPBasic TODO: link
- normal authentication filters
- Internal (datenbase)
- LDAP
- OpenID
- RequestCacheAwareFilter redirects the request if a requests was previously cached
- SecurityContextHolderAwareRequestFilter
- RememberMeFilter for configured auth methods
- Internal
- LDAP
- OpenID
- AnonymousAuthenticationFilter populates an anonymous authentication iff needed
- SessionManagementFilter session-fixation defence
- if an AccessDeniedException occours, the ExceptionTranslationFilter saves the request and redirects the user to the login page or to the access denied page
- FilterSecurityInterceptor currenlty that only admins can access /admin(/?.+)
Authentication
Spring Security needs infos about our users (z.B. passwort, salt from the database, …). You can implement own UserDetailsServices. They return UserDetails objects. An adapter for our user model was written.
methods used
internal (database)
implemented a UserDetailsService
responsible filter: UsernamePasswordAuthenticationFilter
Open ID
pom.xml
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-openid</artifactId> <version>${spring-security.version}</version> </dependency>
responsible filter: OpenIDAuthenticationFilter
LDAP
pom.xml
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-ldap</artifactId> <version>${spring-security.version}</version> </dependency>
see openID and
<ldap-authentication-provider server-ref="ldap://localhost:10389/"/>
responsible filter: UsernamePasswordAuthenticationFilter
setup test ldap server
Spring Security provides a simple ldap server for testing (see 1)
add the following to the XML configuration
<security:ldap-server port="33389" ldif="classpath:users.ldif" />
Don't forget to delete the other ldapserver from the config!
add the following dependencies to the pom:
<!-- LDAP test server --> <dependency> <groupId>org.apache.directory.server</groupId> <artifactId>apacheds-core</artifactId> <version>1.5.5</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.directory.server</groupId> <artifactId>apacheds-server-jndi</artifactId> <version>1.5.5</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.6.0</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.6.0</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.6.0</version> <scope>runtime</scope> </dependency>
Add a .ldif file to the classpath with the user data:
Test sample
dn: ou=pica-users,dc=ub,dc=organization,dc=de objectclass: top objectclass: organizationalUnit ou: pica-users dn: uid=111111111,ou=pica-users,dc=ub,dc=uni-kassel,dc=de objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson objectClass: top cn: John Doe givenName: John uid: 111111111 sn: Doe ou: BB 5 employeeNumber: 999999 employeeType: 30 mail: john@doe.com l: Doe postalCode: 34121 street:: abcdef st: DUMMY carLicense: 0 preferredLanguage: DE userPassword: test
Shibboleth
http://shibboleth.internet2.edu/
TODO: document
HTTP-Basic
TODO: document responsible filter: BasicAuthenticationFilter zuständig.
available methods by Spring Security (and extensions)
OAuth
Version 1: yes
Version 2: yes/no (currently in development)
X.509
http://static.springsource.org/spring-security/site/docs/3.0.x/reference/x509.html
autocreate of users
InitUserFilter
creates a new user if he did't exist before. :(
background: some actions in BibSonomy need a corresponding user in the "user" table gibt (z.B. settings, joining groups, etc.)
responsible filter: http://static.springsource.org/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/web/authentication/preauth/x509/X509AuthenticationFilter.html
more
- Java Authentication and Authorization Service see http://static.springsource.org/spring-security/site/docs/3.0.x/reference/jaas.html
- Central Authentication Service see http://static.springsource.org/spring-security/site/docs/3.0.x/reference/cas.html
- …
implementations
SecurityContextRepository
Because we do not want to save the complete Security context (containing all user details) in the HTTP session, we wrote a special implementation of the SecurtyContextRepository to only save the user name of the currently loggedin user. Configured as follows:
<security:http (...) security-context-repository-ref="contextRepository">(...) <bean id="contextRepository" class="org.bibsonomy.webapp.util.spring.security.UsernameSecurityContextRepository"> <property name="service" ref="databaseUserService" /> </bean>
implementation: org.bibsonomy.webapp.util.spring.security.UsernameSecurityContextRepository
and the corresponding logout handler
<bean id="securityContextLogoutHandler" class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
Brute Force Attacks
no implementation to prevent brute force attacks in Spring Security
wrote class that extends UsernamePasswordAuthenticationFilter and uses our Teergrube implementation users and ips are added by a special AuthenticationFailureHandler implementieren
Internal
RememberMeServices Internal
Spring security provides a RememberMeService for this remember me function: TokenBasedRememberMeServices
This RememberMeService saves the username, expiration date and a signature (configurable key + username + hashed password). If no user is loggedin, this services logs in the user of the cookie.
Open ID
UserDetailsService
Implemented a special user details service: org.bibsonomy.webapp.util.spring.security.userdetailsservice.OpenIDDatabaseUserDetailsService
Attribute Exchange:
- mail address
- nickname
- language
- name
- gender
- country
RememberMeServices OpenID
This implementation uses a cookie to identify the openid user. If the session expired the user is redirected to the OpenID provider (redirects back to the "normal" OpenID filter).
Implementierung: org.bibsonomy.webapp.util.spring.security.rememberMeServices.OpenIDRememberMeService
LDAP
RememberMeServices LDAP
The rememberme service uses a cookie containing the username and the clear password of the user (else we need admin privileges on the LDAP server). The Cookie is encrypted with a private key algorithm.
Configuration
TODO: update The following values are configurable:
- active auth methods (internal, openid, basic, ldap, …) + RememberMe services
- LDAP
- Server
- UserDN
- Search
- private key for crypting cookie
sources + tutorials
http://static.springsource.org/spring-security/site/docs/3.0.x/reference/springsecurity.html
auto create user
Updated